import { GlobalQueueRepo } from '@/entities'
import { CustomLoggerService } from '@/modules'
import { timestampFormat } from '@/util'
import { Injectable, OnModuleInit } from '@nestjs/common'
import { Cron, Interval, Timeout } from '@nestjs/schedule'
import { Queue } from 'bull'
import moment from 'moment'
import { QueueInjection } from 'nestjs-queue'

@Injectable()
export class AppSchedule implements OnModuleInit {
    constructor(
        @QueueInjection() private readonly queue: Queue,
        private readonly globalQueueRepo: GlobalQueueRepo,
        private readonly logger: CustomLoggerService,
    ) {}

    public async onModuleInit() {
        await this.checkQueue()
    }

    @Interval(60e3 * 10) // 60e3 * 10
    public async pubCompanyCount() {
        const now = timestampFormat()
        // this.logger.info(`[AppSchedule] #Interval#300000#${now} 推送企业数据`)
        // await this.companyService.pubCompanyCount()
    }

    @Cron('0 0 * * * *')
    public async checkQueue() {
        const now = timestampFormat()
        this.logger.info(`[AppSchedule] #Cron#0 0 * * * *#${now} 检查队列任务情况`)
        const faileds = await this.queue.getFailed()
        for await (const f of faileds) {
            const queue = this.parseQueue(f)
            const ext = await this.globalQueueRepo.findOne({ queueName: queue.queueName, queueid: queue.queueid })
            if (!ext) {
                await this.globalQueueRepo.save(this.globalQueueRepo.create({ ...queue, ct: queue.time }))
            } else {
                await this.globalQueueRepo.update(ext.id, { ...ext, ...queue, ut: now })
            }
            f.remove()
        }
        const completeds: Record<string, any>[] = await this.queue.getCompleted()
        for await (const c of completeds) {
            const queue = this.parseQueue(c)
            await this.globalQueueRepo.update(
                { queueid: queue.queueid, queueName: queue.queueName },
                { queueStatus: 1, queueValue: queue.queueValue, ut: now },
            )
            c.remove()
        }
    }

    private parseQueue(queue: Record<string, any>) {
        return {
            queueid: queue.id,
            queueName: queue.name,
            queueData: queue.data && typeof queue.data === 'object' ? JSON.stringify(queue.data) : queue.data,
            queueFail: queue.failedReason,
            queueStacktrace:
                Array.isArray(queue.stacktrace) && queue.stacktrace.length > 0
                    ? JSON.stringify(queue.stacktrace)
                    : null,
            queueValue:
                queue.returnvalue && typeof queue.returnvalue === 'object'
                    ? JSON.stringify(queue.returnvalue)
                    : queue.returnvalue,
            time: moment(queue.timestamp || moment()).format('YYYY-MM-DD HH:mm:ss'),
        }
    }
}
